/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.front.web.refund.wx;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.thinkgem.jeesite.common.utils.wx.ClientCustomSSL;
import com.thinkgem.jeesite.common.utils.wx.RandomStringGenerator;
import com.thinkgem.jeesite.common.utils.wx.WeixinSign;
import com.thinkgem.jeesite.common.utils.wx.WeixinXmlTool;
import com.thinkgem.jeesite.modules.config.entity.weixin.ConfigWechat;
import com.thinkgem.jeesite.modules.front.web.pay.wx.WXPayService;
import com.thinkgem.jeesite.modules.pay.entity.log.EcPayLog;
import com.thinkgem.jeesite.modules.pay.service.log.EcPayLogService;
import com.thinkgem.jeesite.modules.refund.entity.log.EcRefundLog;
import com.thinkgem.jeesite.modules.refund.service.log.EcRefundLogService;
import com.thinkgem.jeesite.modules.shop.constant.order.ShopOrderConstant;
import com.thinkgem.jeesite.modules.shop.entity.order.ShopOrder;
import com.thinkgem.jeesite.modules.shop.service.order.ShopOrderService;

/**
 * 购物车Service
 * @author Egan
 * @version 2016-12-15
 */
@Service
@Transactional(readOnly = true)
public class WXRefundService {
	private static Log log = LogFactory.getLog(WXRefundService.class);
	@Autowired EcPayLogService ecPayLogService;
	@Autowired EcRefundLogService ecRefundLogService;
	@Autowired WXPayService wxPayService;
	@Autowired ShopOrderService shopOrderService;
	@Transactional(readOnly = false)
	public Map<String, String> getSignMap(String txnAmt,String orderId,ConfigWechat configWechat) {
		Map<String, String> paramMap = new HashMap<String, String>();	
		int index = txnAmt.indexOf(".");
        if (index < 0) {
        	txnAmt = txnAmt + ".00";
        } else if ((txnAmt.length() - index) < 3) {
            if ((txnAmt.length() - index) == 2) {
            	txnAmt = txnAmt + "0";
            } else if ((txnAmt.length() - index) == 1) {
            	txnAmt = txnAmt + "00";
            }
        } else if ((txnAmt.length() - index) > 3) {// 保留小数超过两位则去除多余的
        	txnAmt = txnAmt.substring(0, index + 3);
        }
        // 金额格式保留两位小数
		BigDecimal orderAmt = new BigDecimal(txnAmt).multiply(new BigDecimal("100")).setScale(0);
		paramMap.put("appid", configWechat.getAppIdGz());
		paramMap.put("mch_id", configWechat.getMchId());
		paramMap.put("nonce_str", RandomStringGenerator.getRandomStringByLength(32));
		// 商户侧传给微信的订单号
		paramMap.put("out_trade_no", orderId);
		// 商户系统内部的退款单号，商户系统内部唯一，同一退款单号多次请求只退一笔
		paramMap.put("out_refund_no", orderId);
		paramMap.put("total_fee", orderAmt.toString());
		paramMap.put("refund_fee", orderAmt.toString());
		paramMap.put("op_user_id", configWechat.getMchId());
		paramMap.put("appKey", configWechat.getAppKey());
		return paramMap;
	}
	
	@Transactional(readOnly = false)
	public Map<String,String> forRefund(String txnAmt,String orderId,ConfigWechat configWechat) throws Exception {
		Map<String,String> resultMap = new HashMap<String, String>();
		//1.查询该订单是否支付成功
		EcPayLog ecPayLog = new EcPayLog();
		ecPayLog.setCoNum(orderId);
		ecPayLog.setOrgCode(configWechat.getMchId());
		ecPayLog = ecPayLogService.getEcPayLogByCoNumOrgCode(ecPayLog);
		
		if ("1".equals(ecPayLog.getPayFlag())) {
			//2.查询该订单是否退过款
			EcRefundLog refundLog = new EcRefundLog();
			refundLog.setOutTradeNo(orderId);
			refundLog.setMchId(configWechat.getMchId());
			EcRefundLog refundLog2 = ecRefundLogService.getEcRefundLogByCoNumMchId(refundLog);
			if (refundLog2 == null) {
				//2.查询该订单是否退过款
				log.debug("orderId:" + orderId + ",txnAmt:" + txnAmt);
				Map<String, String> paramMap = getSignMap(txnAmt,orderId,configWechat);
				// 生成签名
				String sign = WeixinSign.getWeixinRefundSign(paramMap);
				paramMap.put("sign", sign);
				// 生成请求xml报文
		        String xmlStr = WeixinXmlTool.getWeixinRefundXml(paramMap);
		        String result = ClientCustomSSL.doRefund(configWechat.getRefundUrl(), xmlStr,configWechat);
		        Map<String,String[]> parametersMap = WeixinXmlTool.getPayResultFromXml(result);
		        System.out.println("urlMap:" + parametersMap.toString());
		        
		        //TODO
		        String result_code = parametersMap.get("result_code")[0];
		        String return_code = parametersMap.get("return_code")[0];
		        
		        if ("SUCCESS".equals(result_code) && "SUCCESS".equals(return_code)) {
		        	String out_trade_no = parametersMap.get("out_trade_no")[0];
			        String refund_id = parametersMap.get("refund_id")[0];
			        String refund_fee = parametersMap.get("refund_fee")[0];
			        String out_refund_no = parametersMap.get("out_refund_no")[0];
			        String transaction_id = parametersMap.get("transaction_id")[0];
			        String mch_id = parametersMap.get("mch_id")[0];
			        String coupon_refund_fee = parametersMap.get("coupon_refund_fee")[0];
			        String coupon_refund_count = parametersMap.get("coupon_refund_count")[0];
			        refundLog.setCouponRefundCount(coupon_refund_count);
			        refundLog.setCouponRefundFee(coupon_refund_fee);
			        refundLog.setMchId(mch_id);
			        refundLog.setOutRefundNo(out_refund_no);
			        refundLog.setOutTradeNo(out_trade_no);
			        refundLog.setRefundFee(refund_fee);
			        refundLog.setRefundId(refund_id);
			        refundLog.setTransactionId(transaction_id);
		        	ecRefundLogService.save(refundLog);
		        	
		        	ShopOrder order = new ShopOrder();
		        	order.setCode(out_trade_no);
		        	order.setStatus(ShopOrderConstant.ORDER_REFUND_SUCCESS);
		        	
		        	shopOrderService.updateOrderForPaySuccess(order);
		        	resultMap.put("message", "退款成功");
		        } else {
		        	resultMap.put("message", "退款失败");
		        }
		        
			} else {
				resultMap.put("message", "该订单已退款！无法再次退款！");
			}
		} else if ("0".equals(ecPayLog.getPayFlag())) {
			resultMap.put("message", "该订单支付失败！无法退款！");
		} else {
			wxPayService.verifyPayResult(ecPayLog,configWechat);
			ecPayLog = ecPayLogService.getEcPayLogByCoNumOrgCode(ecPayLog);
			if ("1".equals(ecPayLog.getPayFlag())) {
				//2.查询该订单是否退过款
				EcRefundLog refundLog = new EcRefundLog();
				refundLog.setOutTradeNo(orderId);
				refundLog.setMchId(configWechat.getMchId());
				EcRefundLog refundLog2 = ecRefundLogService.getEcRefundLogByCoNumMchId(refundLog);
				if (refundLog2 == null) {
					//2.查询该订单是否退过款
					log.debug("orderId:" + orderId + ",txnAmt:" + txnAmt);
					Map<String, String> paramMap = getSignMap(txnAmt,orderId,configWechat);
					// 生成签名
					String sign = WeixinSign.getWeixinRefundSign(paramMap);
					paramMap.put("sign", sign);
					// 生成请求xml报文
			        String xmlStr = WeixinXmlTool.getWeixinRefundXml(paramMap);
			        String result = ClientCustomSSL.doRefund(configWechat.getRefundUrl(), xmlStr, configWechat);
			        Map<String,String[]> parametersMap = WeixinXmlTool.getPayResultFromXml(result);
			        String result_code = parametersMap.get("result_code")[0];
			        String return_code = parametersMap.get("return_code")[0];
			        
			        if ("SUCCESS".equals(result_code) && "SUCCESS".equals(return_code)) {
			        	String out_trade_no = parametersMap.get("out_trade_no")[0];
				        String refund_id = parametersMap.get("refund_id")[0];
				        String refund_fee = parametersMap.get("refund_fee")[0];
				        String out_refund_no = parametersMap.get("out_refund_no")[0];
				        String transaction_id = parametersMap.get("transaction_id")[0];
				        String mch_id = parametersMap.get("mch_id")[0];
				        String coupon_refund_fee = parametersMap.get("coupon_refund_fee")[0];
				        String coupon_refund_count = parametersMap.get("coupon_refund_count")[0];
				        refundLog.setCouponRefundCount(coupon_refund_count);
				        refundLog.setCouponRefundFee(coupon_refund_fee);
				        refundLog.setMchId(mch_id);
				        refundLog.setOutRefundNo(out_refund_no);
				        refundLog.setOutTradeNo(out_trade_no);
				        refundLog.setRefundFee(refund_fee);
				        refundLog.setRefundId(refund_id);
				        refundLog.setTransactionId(transaction_id);
			        	ecRefundLogService.save(refundLog);
			        	
			        	ShopOrder order = new ShopOrder();
			        	order.setCode(out_trade_no);
			        	order.setStatus(ShopOrderConstant.ORDER_REFUND_SUCCESS);
			        	
			        	shopOrderService.updateOrderForPaySuccess(order);
			        }
				} else {
					resultMap.put("message", "该订单已退款！无法再次退款！");
				}
			} else if ("0".equals(ecPayLog.getPayFlag())) {
				resultMap.put("message", "该订单支付失败！无法退款！");
			} else {
				resultMap.put("message", "该订单支付结果不确定，请稍后再试！");
			}
		}
		return resultMap;
	}
}